package org.jflame.context.lock;

import java.util.concurrent.Callable;
import java.util.function.Consumer;

/**
 * 分布式锁
 * 
 * @author charles.zhang
 */
public interface DistributedLock {

    String LOCK_KEY_PREFIX = "jf_dis_lock";

    /**
     * 获取锁
     * 
     * @param waitTime 等待时间,单位毫秒,获取锁的等待时间不应大于任务的执行时间
     * @return
     */
    boolean lock(long waitTime);

    /**
     * 解锁
     */
    void unlock();

    /**
     * 加锁执行的模板方法
     * 
     * @param <T>
     * @param waitTime 获取锁等待时间
     * @param executor 获取锁后执行的操作
     * @param errorHandler 异常处理
     * @return
     * @throws Exception
     */
    public default <T> T tryLockAndRun(int waitTime, Callable<T> executor, Consumer<Throwable> errorHandler) {
        try {
            if (lock(waitTime)) {
                return executor.call();
            } else {
                throw new RuntimeException("访问太频繁，请稍候再试");
            }
        } catch (Throwable e) {
            errorHandler.accept(e);
            return null;
        } finally {
            unlock();
        }
    }

}
